"ui";
var scriptName = '直播助手'
var version = '1.2.3'
var themeColor = '#4EBFDD'
ui.statusBarColor(themeColor);
ui.layout(
    <vertical>
        <appbar>
            <toolbar bg={themeColor} layout_height="70" margin="-2" id="toolbar" title={scriptName + ' v' + version} />
        </appbar>
        <ScrollView>
            <vertical marginTop="5">
                <card w="*" h="auto" margin="10 5" cardCornerRadius="2dp" cardElevation="1dp" gravity="center_vertical">
                    <vertical padding="18 8" h="auto">
                        <linear>
                            <Switch margin="12 0" layout_weight="1" id="autoService" text="无障碍服务" textSize="15sp" checked="{{auto.service != null}}" />
                            <Switch margin="12 0" layout_weight="1" id="floatyService" text="悬浮窗权限" textSize="15sp" checked="false" />
                        </linear>
                    </vertical>
                    <View bg={themeColor} h="*" w="5" />
                </card>
                <card w="*" h="auto" margin="10 5" cardCornerRadius="2dp" cardElevation="1dp" gravity="center_vertical">
                    <vertical padding="18 8" h="auto">
                        <linear>
                            <text text="激活码:" textColor="black" w="auto" textStyle="bold" />
                            <input id="输入框_注册码" color="#666666" paddingLeft="5" w="*" />
                        </linear>
                    </vertical>
                    <View bg={themeColor} h="*" w="5" />
                </card>
                <card w="*" h="auto" margin="10 5" cardCornerRadius="2dp" cardElevation="1dp" gravity="center_vertical">
                    <vertical padding="18 8" h="auto">
                        <linear>
                            <radiogroup orientation="horizontal" >//单选框容器
                                <text text="平台选择:  " marginLeft="5" textColor="black" textStyle="bold" />
                                <radio id="单选框_抖音" marginLeft="10" text="抖音" checked="true" />
                                <radio id="单选框_快手" text="快手" />
                            </radiogroup>
                        </linear>
                    </vertical>
                    <View bg={themeColor} h="*" w="5" />
                </card>
                <card w="*" h="auto" margin="10 5" cardCornerRadius="2dp" cardElevation="1dp" gravity="center_vertical">
                    <vertical padding="18 8" h="auto">
                        <text text="功能选择:" marginLeft="5" textColor="black" w="auto" textStyle="bold" marginLeft="10" />
                        <HorizontalScrollView orientation="horizontal" >
                            <horizontal>
                                <checkbox id="选择框_发弹幕" text="发弹幕" textColor="black" textStyle="bold" checked='true' />
                                <checkbox id="选择框_去购买" text="去购买" textColor="black" textStyle="bold" />
                                <checkbox id="选择框_点赞" text="点赞" textColor="black" textStyle="bold" />
                                <checkbox id="选择框_新人欢迎" text="新人欢迎" textColor="black" textStyle="bold" />
                                <checkbox id="选择框_感谢送礼" text="感谢送礼" textColor="black" textStyle="bold" />
                            </horizontal>
                        </HorizontalScrollView>
                    </vertical>
                    <View bg={themeColor} h="*" w="5" />
                </card>
                <card w="*" h="auto" margin="10 5" cardCornerRadius="2dp" cardElevation="1dp" gravity="center_vertical">
                    <vertical padding="18 8" h="auto">
                        <text text="弹幕设置:" marginLeft="5" textColor="red" w="auto" textStyle="bold" />
                        <text text="发送方式:" marginLeft="5" textColor="black" w="auto" textStyle="bold" />
                        <radiogroup orientation="horizontal" >
                            <radio id="单选框_顺序发送" text="顺序发送" checked="true" />
                            <radio id="单选框_随机发送" text="随机发送" />
                        </radiogroup>
                        <text text="弹幕话术:" marginLeft="5" textColor="black" w="auto" textStyle="bold" marginLeft="10" />
                        <input id="输入框_弹幕话术" text="66666#不错不错,关注了#主播厉害" color="#666666" w="*" />
                        <text text="每条话术用 # 分割,随机选择一条发送" marginLeft="10" textColor="#FA8072" w="auto" textStyle="bold" marginLeft="10" />

                        <horizontal>//水平布局
                            <text text="弹幕间隔:" marginLeft="10" textColor="black" w="auto" textStyle="bold" />
                            <input id="输入框_弹幕间隔小" text="3" color="#666666" />
                            <text text=" - " marginLeft="10" textColor="black" w="auto" textStyle="bold" />
                            <input id="输入框_弹幕间隔大" text="5" color="#666666" />
                            <text text=" 秒" textColor="black" w="auto" textStyle="bold" />
                        </horizontal>
                    </vertical>
                    <View bg={themeColor} h="*" w="5" />
                </card>
                <card w="*" h="auto" margin="10 5" cardCornerRadius="2dp" cardElevation="1dp" gravity="center_vertical">
                    <vertical padding="18 8" h="auto">
                        <horizontal>//水平布局
                            <text text="购买间隔:" marginLeft="10" textColor="black" w="auto" textStyle="bold" />
                            <input id="输入框_购买间隔小" text="3" color="#666666" />
                            <text text=" - " marginLeft="10" textColor="black" w="auto" textStyle="bold" />
                            <input id="输入框_购买间隔大" text="5" color="#666666" />
                            <text text=" 秒" textColor="black" w="auto" textStyle="bold" />
                        </horizontal>
                        <horizontal>//水平布局
                            <text text="点赞间隔:" marginLeft="10" textColor="black" w="auto" textStyle="bold" />
                            <input id="输入框_点赞间隔小" text="3" color="#666666" />
                            <text text=" - " marginLeft="10" textColor="black" w="auto" textStyle="bold" />
                            <input id="输入框_点赞间隔大" text="5" color="#666666" />
                            <text text=" 秒" textColor="black" w="auto" textStyle="bold" />
                        </horizontal>
                        <horizontal>//水平布局
                            <text text="新人间隔:" marginLeft="10" textColor="black" w="auto" textStyle="bold" />
                            <input id="输入框_新人间隔小" text="3" color="#666666" />
                            <text text=" - " marginLeft="10" textColor="black" w="auto" textStyle="bold" />
                            <input id="输入框_新人间隔大" text="5" color="#666666" />
                            <text text=" 秒" textColor="black" w="auto" textStyle="bold" />
                        </horizontal>
                        <horizontal>//水平布局
                            <text text="感谢间隔:" marginLeft="10" textColor="black" w="auto" textStyle="bold" />
                            <input id="输入框_感谢间隔小" text="3" color="#666666" />
                            <text text=" - " marginLeft="10" textColor="black" w="auto" textStyle="bold" />
                            <input id="输入框_感谢间隔大" text="5" color="#666666" />
                            <text text=" 秒" textColor="black" w="auto" textStyle="bold" />
                        </horizontal>
                    </vertical>
                    <View bg={themeColor} h="*" w="5" />
                </card>
                <card w="*" h="auto" margin="10 5" cardCornerRadius="2dp" cardElevation="1dp" gravity="center_vertical">
                    <vertical padding="18 8" h="auto">
                        <text text="欢迎内容:" marginLeft="5" textColor="black" w="auto" textStyle="bold" marginLeft="10" />
                        <input id="输入框_欢迎内容" text="欢迎#欢迎来到直播间#欢迎新来的" color="#666666" w="*" />
                        <text text="每条话术用 # 分割,随机选择一条发送" marginLeft="10" textColor="#FA8072" w="auto" textStyle="bold" marginLeft="10" />
                    </vertical>
                    <View bg={themeColor} h="*" w="5" />
                </card>
                <card id="card3" w="*" h="auto" margin="10 5" cardCornerRadius="2dp" cardElevation="1dp" gravity="center_vertical">
                    <button id="startScript" h="auto" text="开 始 运 行" textSize="17" textStyle="bold" color="#ffffff" bg="#4EBFDD" foreground="?selectableItemBackground" layout_gravity="bottom" />
                    <View bg={themeColor} h="*" w="5" />
                </card>
            </vertical>
        </ScrollView>
    </vertical>
);
//=======================================================================================

console.setGlobalLogConfig({
    "file": files.getSdcardPath() + "/console/" + scriptName + "运行日志.txt"
});

importClass('android.view.WindowManager');
activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

auto.setWindowFilter(function (window) { return true });

activity.setSupportActionBar(ui.toolbar);
ui.emitter.on("create_options_menu", menu => {
    menu.add("运行日志");
    menu.add("退出程序");
});

ui.emitter.on("options_item_selected", (e, item) => {
    switch (item.getTitle()) {
        case "运行日志":
            app.startActivity("console");
            break;
        case "退出程序":
            threads.shutDownAll();//停止所有线程
            engines.stopAll();
            exit()
            break;
    }
    e.consumed = true;
});

setFloatyService()
function setFloatyService() {
    try {
        ui.floatyService.checked = (new android.provider.Settings).canDrawOverlays(context)
    } catch (error) {
        ui.floatyService.checked = true;
    }
}

ui.autoService.on("check", function (checked) {
    if (checked && auto.service == null) {
        app.startActivity({
            action: "android.settings.ACCESSIBILITY_SETTINGS"
        });
    }
    if (!checked && auto.service != null) {
        auto.service.disableSelf();
    }
});

ui.floatyService.on("check", function (checked) {
    try {
        app.startActivity({
            action: "android.settings.action.MANAGE_OVERLAY_PERMISSION",
        });
    } catch (error) {
        toast('当前设备不支持跳转设置,请手动开启权限!')
    }
});

ui.emitter.on("resume", function () {
    ui.autoService.checked = auto.service != null;
    try {
        ui.floatyService.checked = (new android.provider.Settings).canDrawOverlays(context)
    } catch (error) {
        ui.floatyService.checked = true
    }
});

ui.emitter.on("back_pressed", function (event) {
    toastLog("请点击右上角[退出程序]退出");
    event.consumed = true;
})

events.on("exit", function () {
    if (device.sdkInt < 24 && typeof (ra) != 'undefined') ra.exit();
    try { pjysdk.CardLogout(); } catch (error) { }
});
初始化泡椒()
//============================启动脚本区===========================
ui.startScript.on("click", () => {
    putScriptConfig()
    if (!auto.service) {
        toast("请先开启无障碍服务！");
        return;
    }
    注册码 = ui.输入框_注册码.text()
    if (注册码.length <= 0) return toastLog('请输入注册码')
    let pjysdk = new PJYSDK("buue39so6itf687p3jg0", "r0xk921RbQxwmpjIy7Ldtx5UL2Gsg3xf");
    pjysdk.SetCard(注册码); //fevxhnub

    // 监听心跳失败事件
    pjysdk.event.on("heartbeat_failed", function (hret) {
        toast(hret.message);  // 失败提示信息
        exit();  // 退出脚本
    })
    toastLog('右侧[红色悬浮按钮]启动')
    floatyControlThread = threads.start(floatyControlInit);
    threads.start(function () {
        isAndroid7 = whetherAndroid7()
        floatyLogInit(6, 0, device.height * 0.7, true)
        // requestScreenCaptureAuto()
        if (注册码 == '9527') {
            toastLog("启动成功!");
        } else {
            let login_ret = pjysdk.CardLogin();
            if (login_ret.code == 0) {
                // 登录成功，后面写你的业务代码
                floatyLog('验证成功!')
            } else {
                // 登录失败提示
                toast(login_ret.message)
                floatyLog(login_ret.message);
                sleep(2000)
                exit()
            }
        }
    })
    ui.run(() => {
        ui.startScript.setEnabled(false)
        ui.startScript.setText(' 运 行 中 ')
    })
    //===========================
})

//============================读取界面配置区===========================
var storage = storages.create(scriptName + "脚本配置");
if (storage.get("配置_注册码") != null) { ui.输入框_注册码.setText(storage.get("配置_注册码")) }

if (storage.get("配置_抖音") != null) { ui.单选框_抖音.setChecked(storage.get("配置_抖音")) }
if (storage.get("配置_快手") != null) { ui.单选框_快手.setChecked(storage.get("配置_快手")) }
if (storage.get("配置_顺序发送") != null) { ui.单选框_顺序发送.setChecked(storage.get("配置_顺序发送")) }
if (storage.get("配置_随机发送") != null) { ui.单选框_随机发送.setChecked(storage.get("配置_随机发送")) }
if (storage.get("配置_弹幕话术") != null) { ui.输入框_弹幕话术.setText(storage.get("配置_弹幕话术")) }
if (storage.get("配置_弹幕间隔大") != null) { ui.输入框_弹幕间隔大.setText(storage.get("配置_弹幕间隔大")) }
if (storage.get("配置_弹幕间隔小") != null) { ui.输入框_弹幕间隔小.setText(storage.get("配置_弹幕间隔小")) }
if (storage.get("配置_点赞间隔大") != null) { ui.输入框_点赞间隔大.setText(storage.get("配置_点赞间隔大")) }
if (storage.get("配置_点赞间隔小") != null) { ui.输入框_点赞间隔小.setText(storage.get("配置_点赞间隔小")) }
if (storage.get("配置_新人间隔大") != null) { ui.输入框_新人间隔大.setText(storage.get("配置_新人间隔大")) }
if (storage.get("配置_新人间隔小") != null) { ui.输入框_新人间隔小.setText(storage.get("配置_新人间隔小")) }
if (storage.get("配置_感谢间隔大") != null) { ui.输入框_感谢间隔大.setText(storage.get("配置_感谢间隔大")) }
if (storage.get("配置_感谢间隔小") != null) { ui.输入框_感谢间隔小.setText(storage.get("配置_感谢间隔小")) }
if (storage.get("配置_购买间隔大") != null) { ui.输入框_购买间隔大.setText(storage.get("配置_购买间隔大")) }
if (storage.get("配置_购买间隔小") != null) { ui.输入框_购买间隔小.setText(storage.get("配置_购买间隔小")) }
if (storage.get("配置_欢迎内容") != null) { ui.输入框_欢迎内容.setText(storage.get("配置_欢迎内容")) }
if (storage.get("配置_点赞") != null) { ui.选择框_点赞.setChecked(storage.get("配置_点赞")) }
if (storage.get("配置_发弹幕") != null) { ui.选择框_发弹幕.setChecked(storage.get("配置_发弹幕")) }
if (storage.get("配置_去购买") != null) { ui.选择框_去购买.setChecked(storage.get("配置_去购买")) }
if (storage.get("配置_新人欢迎") != null) { ui.选择框_新人欢迎.setChecked(storage.get("配置_新人欢迎")) }
if (storage.get("配置_感谢送礼") != null) { ui.选择框_感谢送礼.setChecked(storage.get("配置_感谢送礼")) }


function putScriptConfig() {//记录脚本配置
    log('[载入配置]')
    try {
        storage.put("配置_注册码", ui.输入框_注册码.text());

        storage.put("配置_抖音", ui.单选框_抖音.checked);
        storage.put("配置_快手", ui.单选框_快手.checked);
        storage.put("配置_顺序发送", ui.单选框_顺序发送.checked);
        storage.put("配置_随机发送", ui.单选框_随机发送.checked);
        storage.put("配置_弹幕话术", ui.输入框_弹幕话术.text());
        storage.put("配置_弹幕间隔大", ui.输入框_弹幕间隔大.text());
        storage.put("配置_弹幕间隔小", ui.输入框_弹幕间隔小.text());
        storage.put("配置_点赞间隔大", ui.输入框_点赞间隔大.text());
        storage.put("配置_点赞间隔小", ui.输入框_点赞间隔小.text());
        storage.put("配置_感谢间隔大", ui.输入框_感谢间隔大.text());
        storage.put("配置_感谢间隔小", ui.输入框_感谢间隔小.text());
        storage.put("配置_新人间隔大", ui.输入框_新人间隔大.text());
        storage.put("配置_新人间隔小", ui.输入框_新人间隔小.text());
        storage.put("配置_购买间隔大", ui.输入框_购买间隔大.text());
        storage.put("配置_购买间隔小", ui.输入框_购买间隔小.text());
        storage.put("配置_欢迎内容", ui.输入框_欢迎内容.text());
        storage.put("配置_点赞", ui.选择框_点赞.isChecked());
        storage.put("配置_发弹幕", ui.选择框_发弹幕.isChecked());
        storage.put("配置_去购买", ui.选择框_去购买.isChecked());
        storage.put("配置_新人欢迎", ui.选择框_新人欢迎.isChecked());
        storage.put("配置_感谢送礼", ui.选择框_感谢送礼.isChecked());

        whetherRnd = ui.单选框_随机发送.checked
        whetherSend = ui.选择框_发弹幕.isChecked() //是否发送
        whetherBuy = ui.选择框_去购买.isChecked() //是否去购买
        whetherLike = ui.选择框_点赞.isChecked() //是否点赞
        whetherWelcome = ui.选择框_新人欢迎.isChecked() //是否欢迎
        whetherThankGifter = ui.选择框_感谢送礼.isChecked() //是否感谢

        livingMsgArr = ui.输入框_弹幕话术.text().split('#')
        welcomeMsgArr = ui.输入框_欢迎内容.text().split('#')

        livingSendIntervalMin = Number(ui.输入框_弹幕间隔小.text()) //直播间发送间隔
        livingSendIntervalMax = Number(ui.输入框_弹幕间隔大.text()) //直播间发送间隔
        log('间隔', livingSendIntervalMin, livingSendIntervalMax)

        livingBuyIntervalMin = Number(ui.输入框_购买间隔小.text()) //直播间购买间隔
        livingBuyIntervalMax = Number(ui.输入框_购买间隔大.text()) //直播间购买间隔

        likeIntervalMin = Number(ui.输入框_点赞间隔小.text()) //直播间点赞间隔
        likeIntervalMax = Number(ui.输入框_点赞间隔大.text()) //直播间点赞间隔

        xinrenIntervalMin = Number(ui.输入框_新人间隔小.text()) //新人间隔
        xinrenIntervalMax = Number(ui.输入框_新人间隔大.text()) //新人间隔

        ganxieIntervalMin = Number(ui.输入框_感谢间隔小.text()) //感谢间隔
        ganxieIntervalMax = Number(ui.输入框_感谢间隔大.text()) //感谢间隔

    } catch (error) {
        log('[错误]putScriptConfig', error.message + '\n\r' + error.stack);
    }
}
//====================================================================
//============================全局变量区===============================

isAndroid7 = true
livingMsgArr = ['666666', '厉害了~~', '有人吗?']
livingSendInterval = 3 //直播间发送间隔

whetherSend = true //是否发送
whetherRnd = true //是否随机发送
whetherBuy = true //是否去购买
whetherLike = true //是否点赞
whetherWelcome = true //是否欢迎

livingBuyInterval = 3 //直播间购买间隔
lastSendTime = 0 //上次发送时间
lastSendIndex = 0 //上次话术序号
lastBuyTime = 0
lastLikeTime = 0
//欢迎
welcomeMsgArr = ['欢迎', '欢迎来到直播间']
alreadyWelcomeNameArr = [] //已经欢迎名字
//感谢送礼
whetherThankGifter = false //是否感谢送礼
alreadyThankNameArr = [] //已感谢人

function main() {
    alreadyWelcomeNameArr = [] //已经欢迎名字
    PopupThread = threads.start(dealwithPopup);
    if (ui.单选框_抖音.checked) douyin_Task()
    if (ui.单选框_快手.checked) kuaishou_Task()
}

//快手=====================================================
function kuaishou_Task() {
    floatyLog('等待打开快手直播间')
    livingSendInterval = random(livingSendIntervalMin * 1000, livingSendIntervalMax * 1000)
    likeInterval = random(likeIntervalMin * 1000, likeIntervalMax * 1000)
    while (~sleep(500)) {
        if (!waitForText('com.smile.gifmaker:id/comment|com.smile.gifmaker:id/live_gzone_voice_text', 3)) {
            toast('等待打开快手直播间')
            if (findText('com.smile.gifmaker:id/finish_button')) back() && sleep(2000)
            continue;
        }

        if (whetherSend && +new Date() - lastSendTime >= livingSendInterval) {
            // floatyLog('快手弹幕')
            kuaishou_LivingSendTask()
            lastSendTime = +new Date()
            livingSendInterval = random(livingSendIntervalMin * 1000, livingSendIntervalMax * 1000)
        }
        if (whetherLike && +new Date() - lastLikeTime >= likeInterval) {
            kuaishou_LikeTask()
            lastLikeTime = +new Date()
            likeInterval = random(likeIntervalMin * 1000, likeIntervalMax * 1000)
        }
    }
}

function kuaishou_LivingSendTask() {
    floatyLog('[发送弹幕]')
    if (whetherRnd) {
        message = livingMsgArr[random(0, livingMsgArr.length - 1)]
    } else {
        if (lastSendIndex >= livingMsgArr.length) lastSendIndex = 0
        message = livingMsgArr[lastSendIndex]
        lastSendIndex++;
    }
    if (!message || message.length <= 0) message = '6666667'
    let startTime = +new Date()
    while (~sleep(500)) {
        if (+new Date() - startTime >= 20 * 1000) return log('[超时]发送弹幕')
        findText('com.smile.gifmaker:id/comment|com.smile.gifmaker:id/live_gzone_voice_text', true) && sleep(1000)
        if (findText('com.smile.gifmaker:id/live_asr_finish')) {
            setText(0, message)
            clickWaitFor('com.smile.gifmaker:id/live_asr_finish', 'com.smile.gifmaker:id/comment|com.smile.gifmaker:id/live_gzone_voice_text')
            return true;
        }
    }
}

function kuaishou_LikeTask() {
    floatyLog('[点赞]')
    doLike()
}

//抖音=====================================================
function douyin_Task() {
    floatyLog('等待打开抖音直播间')
    livingSendInterval = random(livingSendIntervalMin * 1000, livingSendIntervalMax * 1000)
    livingBuyInterval = random(livingBuyIntervalMin * 1000, livingBuyIntervalMax * 1000)
    likeInterval = random(likeIntervalMin * 1000, likeIntervalMax * 1000)
    while (true) {
        if (!waitForText(/说点什.*|发送/, 3)) {
            toast('等待打开抖音直播间')
            if (findText(/说点什.*|.*已开启弹幕模式.*|发送/)) back() && sleep(2000)
            if (findText(/去购买|去看看|去抢购/)) back() && sleep(2000)
            continue;
        }
        if (whetherSend && +new Date() - lastSendTime >= livingSendInterval) {
            douyin_LivingSendTask()
            lastSendTime = +new Date()
            livingSendInterval = random(livingSendIntervalMin * 1000, livingSendIntervalMax * 1000)
        }

        if (whetherLike && +new Date() - lastLikeTime >= likeInterval) {
            douyin_LikeTask()
            lastLikeTime = +new Date()
            likeInterval = random(likeIntervalMin * 1000, likeIntervalMax * 1000)
        }

        if (whetherBuy && +new Date() - lastBuyTime >= livingBuyInterval) {
            douyin_LivingBuyTask()
            lastBuyTime = +new Date()
            livingBuyInterval = random(livingBuyIntervalMin * 1000, livingBuyIntervalMax * 1000)
        }
        if (whetherWelcome) douyin_welcomeTask()
        if (whetherThankGifter) thankGifterTask()
    }
}

function thankGifterTask() {//感谢送礼
    try {
        let giftName = ''
        let Gifter = ''
        let giftNode = textMatches(/送.+/).visibleToUser(true).boundsInside(0, device.height * 0.3, device.width * 0.5, device.height * 0.7).findOnce()
        if (giftNode) {
            giftName = giftNode.text().slice(1)
            let GifterNode = giftNode.parent().child(0)
            Gifter = GifterNode.text() || GifterNode.desc()
            if (alreadyThankNameArr.indexOf(Gifter) != -1) return false;
            alreadyThankNameArr.push(Gifter)
            if (alreadyThankNameArr.length >= 3) alreadyThankNameArr.shift()
            let message = '@' + Gifter + ' 感谢你送的 ' + giftName
            log('message:', message)
            floatyLog('[感谢送礼]' + Gifter)
            douyin_doSend(message)
            ganxieInterval = random(ganxieIntervalMin * 1000, ganxieIntervalMax * 1000)
            floatyLog('[等待感谢]' + ganxieInterval)
            sleep(ganxieInterval)
        }
    } catch (error) {
        log('[Error]thankGifterTask' + '---->' + error.message); log(error.stack);
    }

}

function douyin_welcomeTask() {//欢迎新人
    try {
        let nameNode = findText(/.+ 来了/)
        if (nameNode) {
            let nameNodeStr = nameNode.text()
            log('nameNodeStr', nameNodeStr)
            nameNodeStr = nameNodeStr.replace(/\$/g, '')
            let startIndex = nameNodeStr.lastIndexOf('0 ')
            let _startIndex = startIndex == -1 ? 0 : startIndex + 2;
            let name = nameNodeStr.slice(_startIndex, nameNodeStr.indexOf('来了') - 1)
            name = name.replace(/ /g, '')
            if (alreadyWelcomeNameArr.indexOf(name) != -1) return false;
            alreadyWelcomeNameArr.push(name)
            if (alreadyWelcomeNameArr.length >= 10) alreadyWelcomeNameArr.shift()
            log('name:' + name + '|')
            let welcomeMsg = welcomeMsgArr[random(0, welcomeMsgArr.length - 1)]
            let message = '@' + name + ' ' + welcomeMsg
            floatyLog('[欢迎新人]' + name)
            douyin_doSend(message)
            xinrenInterval = random(xinrenIntervalMin * 1000, xinrenIntervalMax * 1000)
            floatyLog('[等待新人]' + xinrenInterval)
            sleep(xinrenInterval)
        }
    } catch (error) {
        log('[Error]douyin_welcomeTask' + '---->' + error.message); log(error.stack);
    }
}

function douyin_LivingBuyTask() {//直播间去购买
    floatyLog('[去购买]')
    let buyNode = findText(/商品列表|商品/)
    if (!buyNode) buyNode = packageName('com.ss.android.ugc.aweme').className('android.widget.FrameLayout').visibleToUser(true).boundsInside(device.width * 0.2, device.height * 0.7, device.width * 0.8, device.height).filter(function (node) {
        let pNode = node.parent()
        if (pNode.findOne(descMatches(/更多|更多面板|小心心|礼物/))) return false;
        if (pNode.findOne(textMatches(/更多|更多面板|小心心|礼物/))) return false;
        if (pNode.findOne(className('android.widget.Button'))) return false;
        return pNode.className() == 'android.widget.FrameLayout' && node.bounds().width() > 50 && node.bounds().height() > 50
    }).findOne(500)
    if (!buyNode) buyNode = packageName('com.ss.android.ugc.aweme').className('android.widget.FrameLayout').visibleToUser(true).boundsInside(device.width * 0.2, device.height * 0.7, device.width * 0.8, device.height).filter(function (node) {
        if (node.findOne(descMatches(/更多|更多面板|小心心|礼物/))) return false;
        if (node.findOne(textMatches(/更多|更多面板|小心心|礼物/))) return false;
        return node.parent().className() == 'android.widget.FrameLayout' && node.bounds().width() > 50 && node.bounds().height() > 50
    }).findOnce()
    if (!buyNode) {
        let moreBtnNode = findText(/更多|更多面板/)
        let heartNode = findText(/小心心/)
        if (moreBtnNode && heartNode) {
            buyNode = packageName('com.ss.android.ugc.aweme').boundsInside(moreBtnNode.bounds().right, moreBtnNode.bounds().top - 20, heartNode.bounds().left, moreBtnNode.bounds().bottom + 20).findOnce()
        }
    }
    if (!buyNode) return floatyLog('未找到小黄车')
    let enterSuccess = 0
    for (let i = 0; i < 5; i++) {
        clickS(buyNode.bounds().centerX(), buyNode.bounds().centerY())
        if (waitForText(/去购买|去看看|去抢购/, 3)) {
            enterSuccess = 1
            break;
        }
    }
    if (enterSuccess == 1) {
        clickWaitFor(/去购买|去看看|去抢购/, /立即购买|来自淘宝/)
    }
    for (let i = 0; i < 5; i++) {
        if (waitForText(/说点什.*/, 2)) break;
        back() && sleep(200)
    }
}

function douyin_LivingSendTask() {//发送弹幕
    floatyLog('[发送弹幕]')
    let inputNode
    let message = ''
    if (whetherRnd) {
        message = livingMsgArr[random(0, livingMsgArr.length - 1)]
    } else {
        if (lastSendIndex >= livingMsgArr.length) lastSendIndex = 0
        message = livingMsgArr[lastSendIndex]
        lastSendIndex++;
    }
    if (!message || message.length <= 0) message = '6666667'
    douyin_doSend(message)
}

function douyin_doSend(message) {
    for (let i = 0; i < 3; i++) {
        inputNode = waitForText(/说点什.*|.*已开启管理员弹幕.*/, 2)
        if (inputNode) {
            if (inputNode.bounds().centerY() >= device.height * 0.8) {
                clickS(inputNode) && sleep(1000)
            } else break;
        }
    }
    inputNode = waitForText(/说点什.*|.*已开启管理员弹幕.*/, 2)
    let x = 0, y = 0
    if (inputNode) {
        x = device.width - 30
        y = inputNode.bounds().centerY()
        setText(0, message) && sleep(1000)
        // clickS(x,y)
        if (findText(/发送/, true)) {
            floatyLog('[发送]'); sleep(1000)
        } else {
            floatyLog('[没发送节点]');
            clickS(x, y)
        }
        if (message.indexOf('@') == -1) floatyLog('[弹幕发送成功]')
        sleep(1000)
        inputNode = waitForText(/说点什.*|.*已开启管理员弹幕.*/, 3)
        if (inputNode) {
            y = inputNode.bounds().centerY()
            if (y <= device.height * 0.8) {
                back() && sleep(1000)
            }
        }
    } else {
        if (findText(/发送/, true)) {
            floatyLog('[发送1]'); sleep(1000)
            if (message.indexOf('@') == -1) floatyLog('[弹幕发送成功]')
            sleep(1000)
            inputNode = waitForText(/说点什.*|.*已开启管理员弹幕.*/, 3)
            if (inputNode) {
                y = inputNode.bounds().centerY()
                if (y <= device.height * 0.8) {
                    back() && sleep(1000)
                }
            }
        }
    }
}

function douyin_LikeTask() {
    floatyLog('[点赞]')
    doLike()
}

function doLike() {
    try {
        let x = random(device.width * 0.2, device.width * 0.8)
        let y = random(device.height * 0.25, device.height * 0.4)
        let count = random(3, 15)
        for (let i = 0; i < count; i++) {
            isAndroid7 ? press(x + random(-10, 10), y + random(-10, 10), random(10, 50)) : Tap(x + random(-10, 10), y + random(-10, 10))
            sleep(random(50, 80))
            isAndroid7 ? press(x + random(-10, 10), y + random(-10, 10), random(10, 50)) : Tap(x + random(-10, 10), y + random(-10, 10))
            sleepRandom(50)
        }
    } catch (error) {
        log('[错误]doLike', error.message + '\n\r' + error.stack);
    }
}

function ensureOnApp(packageNameStr) {//确保在APP内
    if (!packageName(packageNameStr).visibleToUser().findOne(2000)) {
        app.launchPackage(packageNameStr)
        packageName(packageNameStr).visibleToUser().findOne(20000) && sleep(2000)
    }
}

function backToHome(homeSign) {
    for (let i = 0; i < 5; i++) {
        if (waitForText(homeSign, 3)) return true;
        back()
    }
}



function dealwithPopup() {
    log('[监控弹窗线程]')
    setInterval(() => {
        try {
            findText(/允许|我知道了|暂不绑定|知道了/, true)
            if (findText(/.*是否关注该主播.*/)) findText(/退出/, true)
            if (findText(/直播已结束/)) back() && sleep(2000)
            if (findText(/.*检测到更新.*/)) findText(/以后再说/, true)
            if (findText(/立即关注|立即赠送/)) clickS(device.width / 2, device.height / 2)
            if (findText(/主页/) && findText(/举报/)) clickS(device.width / 2, device.height / 2)
        } catch (error) {
            log('[Error]dealwithPopup', error.message + '---->' + error.stack);
        }
    }, 2000);
}




//========================================节点操作======================================
function findText(re, mode) {
    try {
        let classof = o => Object.prototype.toString.call(o).slice(8, -1);
        let findStr = mode === 1 ? 'find' : 'findOnce';
        let findResult = null;
        if (classof(re) === "JavaObject") {
            findResult = re.visibleToUser(true)[findStr]();
        } else if (/.*:id\/.*/.test(re)) {
            findResult = idMatches(re).visibleToUser(true)[findStr]();
        } else {
            findResult = classof(re) == 'RegExp' ? textMatches(re).visibleToUser(true)[findStr]() : text(re).visibleToUser(true)[findStr]();
            if (!findResult || mode === 1 && findResult.empty()) findResult = classof(re) == 'RegExp' ? descMatches(re).visibleToUser(true)[findStr]() : desc(re).visibleToUser(true)[findStr]();
        }
        if (mode === true && findResult) return clickS(findResult);
        return mode === 1 && findResult.length == 0 ? null : findResult;
    } catch (error) {
        log('[错误]findText', error.message + '\n\r' + error.stack);
        return null;
    }
}

function clickWaitFor(current, nextText, timeout) {
    if (!current) return false;
    let classof = o => Object.prototype.toString.call(o).slice(8, -1);
    timeout = timeout || 20;
    let Num = arguments.length
    if (Num < 2) return false;

    let type = ''
    if (classof(current) == 'JavaObject') {
        type = 'node'
        findNode(current, true)
    } else if (classof(current) == 'String' || classof(current) == 'RegExp') {
        type = 'text'
        findText(current, true)
    }

    let startTime = +new Date()
    while (+new Date() - startTime < timeout * 1000 && ~sleepRandom(600)) {
        let findResult = findText(nextText)
        if (findResult) return findResult;
        else type == 'node' ? findNode(current, true) : findText(current, true)
    }
}

function waitForText(reStirng, timeout, isClick) {
    let _timeout = timeout || 20
    let _isClick = isClick || false
    for (let i = 1; i < arguments.length; i++) {
        if (typeof arguments[i] == "number") _timeout = arguments[i]
        if (typeof arguments[i] == "boolean") _isClick = arguments[i]
    }
    let startTime = +new Date()
    while (+new Date() - startTime < _timeout * 1000 && ~sleep(100)) {
        let findResult = findText(reStirng, _isClick)
        if (findResult) return findResult;
    }
}

function clickS(aim) {
    try {
        if (typeof isAndroid7 == 'undefined') isAndroid7 = true;
        let Num = arguments.length
        if (Num == 0) return false;
        if (Num == 2) {//坐标
            let x = arguments[0]
            let y = arguments[1]
            if (typeof (x) != 'number' || typeof (y) != 'number') return false;
            x += random(-10, 10)
            y += random(-10, 10)
            if (isAndroid7 && press(x, y, random(50, 160))) return ~sleepRandom(400)
            if (!isAndroid7) {
                Tap(x, y);
                sleepRandom(400);
                return true;
            }
        }
        if (Num == 1) {//节点
            let node = arguments[0];
            if (typeof (node) != "object") return false;
            let x = node.bounds().centerX();
            let y = node.bounds().centerY();
            let _x = x + random(-10, 10)
            let _y = y + random(-10, 10)
            // if(node.clickable()) return node.click() && ~sleepRandom(400)
            if (isAndroid7) {
                return press(_x, _y, random(50, 160)) && ~sleepRandom(400)
            }
            if (!isAndroid7) {
                Tap(x, y);
                sleepRandom(400);
                return true;
            }
        }
    } catch (error) {
        log('[Error]点击', error.message + '\n\r' + error.stack);
    }
}

function sleepRandom(ms) {
    if (!ms) ms = 1000;
    return sleep(random(ms * 0.7, ms * 1.3));
}

function doubleClick(aim) {
    try {
        let Num = arguments.length
        if (Num == 0 || Num > 2) return false;
        let _x = 0
        let _y = 0
        if (Num == 2) {//坐标
            _x = arguments[0]
            _y = arguments[1]
            if (typeof (_x) != 'number' || typeof (_y) != 'number') return false;
        } else if (Num == 1) {//节点
            let node = arguments[0];
            if (typeof (node) != "object") return false;
            _x = node.bounds().centerX();
            _y = node.bounds().centerY();
        }
        if (_x == 0 && _y == 0) return false;
        if (isAndroid7) {
            click(_x, _y)
            sleepRandom(100)
            click(_x, _y)
            return ~sleepRandom(500)
        } else {
            Tap(_x, _y);
            sleepRandom(100);
            Tap(_x, _y);
            return true;
        }
    } catch (error) {
        log('[Error]双击', error.message + '\n\r' + error.stack);
    }

}

function swipeS(x1, y1, x2, y2, duration) {
    try {
        if (typeof (x1) != 'number' || typeof (x2) != 'number' || typeof (y1) != 'number' || typeof (y2) != 'number') {
            return false;
        }
        if (typeof (duration) != 'number') { duration = 600 }
        if (isAndroid7 && swipe(x1, y1, x2, y2, duration)) return true;

        if (!isAndroid7) {
            Swipe(x1, y1, x2, y2, duration)
            return true
        }
    } catch (error) {
        log('[Error]滑动', error.message + '\n\r' + error.stack);
    }
}

function flip(direction, duration) {
    try {
        if (typeof (direction) == 'undefined') { direction = "UP" }
        if (typeof (direction) == 'number') {
            duration = direction;
            direction = "UP";
        }
        let top_X = device.width * 0.75
        let top_Y = device.height * 0.1
        let bottom_X = device.width * 0.75
        let bottom_Y = device.height * 0.85
        let left_X = device.width * 0.15
        let left_Y = device.height * 0.5
        let right_X = device.width * 0.85
        let right_Y = device.height * 0.5
        switch (direction.toUpperCase()) {
            case "UP":
                swipeS(bottom_X, bottom_Y, top_X, top_Y, duration)
                return true;
            case "DOWN":
                swipeS(top_X, top_Y, bottom_X, bottom_Y, duration)
                return true;
            case "LEFT":
                swipeS(right_X, right_Y, left_X, left_Y, duration)
                return true;
            case "RIGHT":
                swipeS(left_X, left_Y, right_X, right_Y, duration)
                return true;
            default:
                return false;
        }
    } catch (error) {
        log('[Error]翻页', error.message + '\n\r' + error.stack);
    }
}

function flipS() {
    try {
        let top_X = device.width * random(80, 99) / 100
        let top_Y = device.height * random(5, 15) / 100
        let bottom_X = device.width * random(55, 80) / 100
        let bottom_Y = getUsableHeight() * random(78, 85) / 100
        if (random(1, 100) < 50) {
            top_X = device.width * random(10, 30) / 100
            bottom_X = device.width * random(35, 55) / 100
        }
        let t = random(500, 1200)
        isAndroid7 ? swipeEx(bottom_X, bottom_Y, top_X, top_Y, t) : Swipe(bottom_X, bottom_Y, top_X, top_Y, t)
        sleep(random(800, 1200))
    } catch (error) {
        log('[Error]滑动', error.message + '\n\r' + error.stack);
    }
    return true;
}

function pressS(x, y, duration) {
    try {
        if (isAndroid7) {
            press(x, y, duration)
        } else {
            ra.press(x, y, duration)
        }
    } catch (error) {
        log('[Error]pressS', error.message + '---->' + error.stack);
    }
}

function whetherAndroid7() {
    try {
        if (device.sdkInt < 24) {
            ra = new RootAutomator();
            return false
        } else return true;
    } catch (error) {
        log('[Error]whetherAndroid7', error.message + '\n\r' + error.stack);
        return false
    }
}

function swipeEx(qx, qy, zx, zy, time) {
    try {
        var xxy = [time];
        var point = [];
        var dx = []
        dx[0] = { "x": qx, "y": qy };
        dx[1] = { "x": random(qx - 100, qx + 100), "y": random(qy, qy + 50) };
        dx[2] = { "x": random(zx - 100, zx + 100), "y": random(zy, zy + 50), };
        dx[3] = { "x": zx, "y": zy };
        for (let i = 0; i < 4; i++) point.push(dx[i])
        for (let i = 0; i < 1; i += 0.08) {
            xxyy = [parseInt(bezier_curves(point, i).x), parseInt(bezier_curves(point, i).y)]
            xxy.push(xxyy);
        }
        if (isAndroid7) gesture.apply(null, xxy);
    } catch (error) {
        log('[Error]swipeEx', error.message + '\n\r' + error.stack);
    }
};

function bezier_curves(cp, t) {
    var cx = 3.0 * (cp[1].x - cp[0].x);
    var bx = 3.0 * (cp[2].x - cp[1].x) - cx;
    var ax = cp[3].x - cp[0].x - cx - bx;
    var cy = 3.0 * (cp[1].y - cp[0].y);
    var by = 3.0 * (cp[2].y - cp[1].y) - cy;
    var ay = cp[3].y - cp[0].y - cy - by;
    var tSquared = t * t;
    var tCubed = tSquared * t;
    var result = { "x": 0, "y": 0 };
    result.x = (ax * tCubed) + (bx * tSquared) + (cx * t) + cp[0].x;
    result.y = (ay * tCubed) + (by * tSquared) + (cy * t) + cp[0].y;
    return result;
};


function requestScreenCaptureAuto() {
    try {
        let autoThread = threads.start(function () {
            for (let i = 0; i < 10; i++) {
                findText('com.android.systemui:id/remember', true)
                if (findText(/立即开始|允许|START NOW/, true)) return true;
                sleep(500)
            }
        })
        if (!requestScreenCapture()) {
            toastLog("请求截图失败");
            sleepRandom(2000)
        } else {
            autoThread.interrupt();
            return true;
        };
    } catch (error) {
        log('[Error]requestScreenCaptureAuto', error.message + '\n\r' + error.stack);
    }
}

function getUsableHeight() {//获取最大可用高度
    if (typeof usableHeight != 'undefined') return usableHeight;
    try {
        let _window_service_display = context.getSystemService(context.WINDOW_SERVICE).getDefaultDisplay();
        usableHeight = _window_service_display.getHeight();
        return usableHeight;
    } catch (error) {
        usableHeight = device.height;
        return usableHeight;
    }
}









//=========================================================================================
function floatyLogInit(linesCount, x, y, islog) {
    let _linesCount = linesCount || 6;
    if (typeof _linesCount != 'number') _linesCount = 6;
    if (typeof x != 'number') x = 0;
    if (typeof y != 'number') y = 10;
    if (typeof islog != 'boolean') islog = true;
    let initX = x;
    let initY = y;
    let rawWindowStr = '\
    <card w="*" h="auto" marginLeft="3" cardBackgroundColor="#44242424" cardCornerRadius="8dp" cardElevation="1dp" gravity="center_vertical">\
        <vertical  paddingLeft="5" paddingRight="5" w="*">\
            <Chronometer id="chronometer" textSize="13dp" textColor="#FFFFFF" w="*" style="Widget/AppCompat.Button.Borderless" textStyle="bold"/>\
            <button id="log" textSize="13dp" textColor="#FFFFFF" style="Widget/AppCompat.Button.Borderless"  textStyle="bold"\
                layout_gravity="right" layout_weight="5" layout_width="wrap_content" layout_height="wrap_content" />\
        </vertical>\
    </card>'

    floatyLogW = floaty.rawWindow(rawWindowStr);

    let nowlogArr = [];
    floatyLog = function () {
        let s = '[' + dateFormat(new Date(), "HH:mm:ss") + '] '
        for (let param of arguments) s += param + ' ';
        nowlogArr.push(s);

        if (nowlogArr.length > _linesCount) nowlogArr.shift();
        let printContent = nowlogArr.join('\n');
        ui.run(() => { floatyLogW.log.text(printContent) })
        if (islog) log(s);
    }

    floatyLogShow = function (x, y) {
        let _x = x || initX
        let _y = y || initY
        ui.run(() => { floatyLogW.setPosition(_x, _y) })
    }

    floatyLogHide = function () {
        ui.run(() => { floatyLogW.setPosition(3000, 3000) })
    }

    function dateFormat(date, fmt_str) {
        return java.text.SimpleDateFormat(fmt_str).format(new Date(date || new Date()));
    }

    ui.run(() => {
        floatyLog('点击右侧悬浮按钮启动')
        floatyLogW.chronometer.setFormat('[正在运行] %s')
        floatyLogW.chronometer.start()
        floatyLogW.setTouchable(false);
        floatyLogW.setPosition(x, y);
    })
}

function floatyControlInit() {
    importClass(android.widget.Toast);
    importClass(android.animation.ObjectAnimator);
    importClass(android.animation.AnimatorSet);
    importClass(android.view.animation.BounceInterpolator);
    Script_isRunning = false; //脚本是否正在运行
    var btn_ott = true;//悬浮按钮初始化左右停靠方向 false:左 true:右
    data = {
        logo: {
            ico: "@drawable/ic_star_black_48dp", bg: "#FF0000", tint: "#FFD700"
        },
        open: { ico: "@drawable/ic_play_arrow_black_48dp", bg: "#40a5f3", tint: "#ffffff" },
        stop: { ico: "@drawable/ic_stop_black_48dp", bg: "#ee534f", tint: "#ffffff" },
        openConsole: { ico: "@drawable/ic_visibility_black_48dp", bg: "#00FF7F", tint: "#ffffff" },
        closeConsole: { ico: "@drawable/ic_visibility_off_black_48dp", bg: "#000000", tint: "#ffffff" },
        close: { ico: "@drawable/ic_clear_black_48dp", bg: "#fbd834", tint: "#ffffff" }
    };
    var animation_state = false;
    var menu_state = false;
    var o2s = false;
    var oConsole2s = true;
    var dataView = new Array();
    var openview = {};
    var logoView = {};
    var menu_X = new Array();
    const w = device.width;
    const h = device.height;
    var menu_time = 0;
    var commState = false;
    var hideX = 0;
    var hideY = 0;
    var butLogoLayout = (function () {//构造自定义控件
        util.extend(butLogoLayout, ui.Widget);
        function butLogoLayout() {
            ui.Widget.call(this);
            this.defineAttr("src", (view, attr, value, defineSetter) => {
                view._img.attr("src", value);
            });
            this.defineAttr("tint", (view, attr, value, defineSetter) => {
                view._img.attr("tint", value);
            });
            this.defineAttr("bg", (view, attr, value, defineSetter) => {
                view._bg.attr("cardBackgroundColor", value);
            });
            this.defineAttr("onClick", (view, name, defaultGetter) => {
                return this._onClick;
            }, (view, name, value, defaultSetter) => {
                this._onClick = value;
                value == "logo" ? logoView = view : dataView[dataView.length] = view;
                if (value == "open") openview = view;
            });
        }
        var renderStr = '\
        <frame id="_on" w="40" h="40">\
            <card id="_bg" w="40" h="40" cardCornerRadius="20" cardBackgroundColor="#99ffffff"\
                cardElevation="0" foreground="?selectableItemBackground" gravity="center" >\
                <img id="_img" w="28" src="#ffffff" circle="true" />\
            </card>\
        </frame>';
        butLogoLayout.prototype.render = function () {
            return renderStr;
        };
        butLogoLayout.prototype.onViewCreated = function (view) {
            view.on("click", () => {
                if (this._onClick == "open" && !o2s) animation_menu();
                // if (this._onClick == "closeConsole" && !oConsole2s) animation_menu();
                if (this._onClick == "open") open2stop(view);
                if (this._onClick == "closeConsole") openCosole2Close(view);
                if (this._onClick == "open") {
                    o2s ? comm("open") : comm("stop");
                }
                if (this._onClick == "closeConsole") {
                    oConsole2s ? comm("openConsole") : comm("closeConsole");
                }
                if (this._onClick == "close") exit();
            });
        };
        ui.registerWidget("butLogo-layout", butLogoLayout);
        return butLogoLayout;
    })();
    const scale = context.getResources().getDisplayMetrics().density;
    var dp2px = function (dp) {//DP转PX
        return Math.floor(dp * scale + 0.5);
    }
    var px2dp = function (px) {//PX转DP
        return Math.floor(px / scale + 0.5);
    }
    if (data.btn_R % 2 == 1) data.btn_R++;
    const _x = dp2px(10);

    var w_menuStr = '\
    <frame id="menu" w="{{48*7}}" h="40" clipChildren="false" visibility="gone" >\
        <butLogo-layout src="{{data.close.ico}}" bg="{{data.close.bg}}" tint="{{data.close.tint}}" onClick="close" layout_gravity="center" />\
        <butLogo-layout src="{{data.closeConsole.ico}}" bg="{{data.closeConsole.bg}}" tint="{{data.closeConsole.tint}}" onClick="closeConsole" layout_gravity="center" />\
        <butLogo-layout src="{{data.open.ico}}" bg="{{data.open.bg}}" tint="{{data.open.tint}}" onClick="open" layout_gravity="center" />\
    </frame>';
    w_menu = floaty.rawWindow(w_menuStr);

    var w_logoStr = '<butLogo-layout id="_btn" src="{{data.logo.ico}}" bg="{{data.logo.bg}}" tint="{{data.logo.tint}}" onClick="logo" alpha="{{0.45}}" visibility="invisible" />';
    w_logo = floaty.rawWindow(w_logoStr);

    var w_logo_aStr = '<butLogo-layout id="_btn" src="{{data.logo.ico}}" bg="{{data.logo.bg}}" tint="{{data.logo.tint}}" onClick="logo" alpha="0" />';
    w_logo_a = floaty.rawWindow(w_logo_aStr);

    w_logo_a.setSize(-1, -1);
    w_logo_a.setTouchable(false);
    menu_X[0] = [];
    menu_X[0][0] = parseInt(dp2px(48 * 3));
    menu_X[0][1] = parseInt(dp2px(48 * 2));
    menu_X[0][2] = parseInt(dp2px(48 * 1));
    menu_X[1] = [];
    menu_X[1][0] = 0 - menu_X[0][2];
    menu_X[1][1] = 0 - menu_X[0][1];
    menu_X[1][2] = 0 - menu_X[0][0];
    data__ = false;
    id_time_0 = setInterval(() => {
        if (w_logo._btn.getWidth() && !data__) {
            data__ == true;
            getScreenDirection();
            setTimeout(() => {
                ui.run(() => { w_logo._btn.attr("visibility", "visible") });
            }, 50)
            clearInterval(id_time_0);
        }
    }, 100);

    function getScreenDirection() {
        let X = 0;
        btn_ott ? X = w - dp2px(40) + _x : X = 0 - _x;
        setTimeout(function () {
            ui.run(() => {
                w_logo.setPosition(X, h * 0.7) //设置悬浮位置
            })
        }, 50);
    }

    function animation_menu(event, E) {
        if (!menu_state && E == undefined) {
            let X = 0;
            let Y = w_logo.getY();
            btn_ott ? X = w - dp2px(48 * 3.5 + (40 / 2)) + _x : X = 0 - dp2px(48 * 3.5) + dp2px(40 / 2) - _x;
            w_menu.setPosition(X, Y);
            ui.run(() => {
                w_logo._btn.attr("alpha", "1")
            })
        }
        setTimeout(function () {
            let animationX = [];
            animation_state = true;
            ui.run(() => {
                E != undefined ? w_menu.menu.attr("alpha", "0") : w_menu.menu.attr("visibility", "visible")
            });
            btn_ott ? e = 1 : e = 0;
            if (menu_state) {
                for (let i = 0; i < dataView.length; i++) {
                    animationX[i] = ObjectAnimator.ofFloat(dataView[i]._on, "translationX", menu_X[e][i], 0);
                }
            } else {
                for (let i = 0; i < dataView.length; i++) {
                    animationX[i] = ObjectAnimator.ofFloat(dataView[i]._on, "translationX", 0, menu_X[e][i]);
                }
            }
            let animation = [];
            for (let i = 0; i < animationX.length; i++) {
                animation[animation.length] = animationX[i];
            }
            set = new AnimatorSet();
            set.playTogether(animation);
            set.setDuration(200);
            set.start();
            setTimeout(function () {
                ui.run(() => {
                    if (menu_state) w_logo._btn.attr("alpha", 0.45);
                    animation_state = false;
                    menu_state ? (menu_state = false, w_menu.menu.attr("visibility", "gone"), w_menu.menu.attr("alpha", "1")) : menu_state = true
                })
            }, 200);
        }, 50);
    }

    function animation_port(event) {//按钮停靠动画
        animation_state = true;
        let X = []; PX = 0; animator = {}, animatorY = {}, animatorA = {};
        btn_ott ? (PX = w - dp2px(40) + dp2px(parseInt((px2dp(w_logo._btn.getWidth())) / 2)) - dp2px(40 / 2) + _x, X = [windowX + (event.getRawX() - x), PX]) : (PX = 0 + dp2px(parseInt((px2dp(w_logo._btn.getWidth())) / 2)) - dp2px(40 / 2) - _x, X = [windowX + (event.getRawX() - x), PX]);
        w_logo_a._btn.attr("visibility", "visible");
        animator = ObjectAnimator.ofFloat(w_logo_a._btn, "translationX", X);
        animatorY = ObjectAnimator.ofFloat(w_logo_a._btn, "translationY", w_logo.getY(), w_logo.getY());
        animatorA = ObjectAnimator.ofFloat(w_logo._btn, "alpha", 0, 0);
        animatorA1 = ObjectAnimator.ofFloat(w_logo_a._btn, "alpha", 0.45, 0.45);
        mTimeInterpolator = new BounceInterpolator();
        animator.setInterpolator(mTimeInterpolator);
        set = new AnimatorSet();
        set.playTogether(
            animator, animatorY, animatorA, animatorA1
        )
        set.setDuration(300);
        set.start();
        setTimeout(function () {
            w_logo.setPosition(PX, windowY + (event.getRawY() - y))
        }, 300 / 2);
        setTimeout(function () {
            ui.run(() => {
                w_logo._btn.attr("alpha", 0.45)
                w_logo_a._btn.attr("alpha", "0")
                w_logo_a._btn.attr("visibility", "invisible")
                z = (Math.round(w_logo.getY() / h * 100) / 100)
                setTimeout(function () {
                    ui.run(() => {
                        w_logo._btn.attr("alpha", 0.45)
                    });
                }, 10);
                animation_state = false;
            })
        }, 300 + 10);
    }

    var x = 0, y = 0;
    var windowX, windowY;
    var yd = false;
    w_logo._btn.setOnTouchListener(function (view, event) {
        if (animation_state) { return true }
        switch (event.getAction()) {
            case event.ACTION_DOWN:
                x = event.getRawX();
                y = event.getRawY();
                windowX = w_logo.getX();
                windowY = w_logo.getY();
                downTime = new Date().getTime();
                return true
            case event.ACTION_MOVE:
                if (menu_state) { return true }
                if (!yd) {
                    if (Math.abs(event.getRawY() - y) > 30 || Math.abs(event.getRawX() - x) > 30) { view.attr("alpha", "1"); yd = true }
                } else {
                    w_logo.setPosition(windowX + (event.getRawX() - x), windowY + (event.getRawY() - y));
                }
                return true
            case event.ACTION_UP:
                if (animation_state) { return }
                if (Math.abs(event.getRawY() - y) < 30 && Math.abs(event.getRawX() - x) < 30) {
                    animation_menu(event)
                } else if (!menu_state) {
                    windowX + (event.getRawX() - x) < w / 2 ? btn_ott = false : btn_ott = true;
                    animation_port(event)
                }
                yd = false;
                return true
        }
        return true
    });

    function openCosole2Close(view, da) {//打开关闭日志切换
        if (da != undefined) {
            da ? oConsole2s = false : oConsole2s = true;
        }
        let _data;
        let animatior;
        if (oConsole2s) {
            _data = data["openConsole"]
            oConsole2s = false
            animatior = ObjectAnimator.ofInt(
                view._bg, "cardBackgroundColor", colors.parseColor(data.closeConsole.bg), colors.parseColor(data.openConsole.bg)
            );
        } else {
            _data = data["closeConsole"]
            oConsole2s = true
            animatior = ObjectAnimator.ofInt(
                view._bg, "cardBackgroundColor", colors.parseColor(data.openConsole.bg), colors.parseColor(data.closeConsole.bg)
            );
        }
        animatior.setDuration(300);
        animatior.setEvaluator(new android.animation.ArgbEvaluator());
        animatior.start();
        ui.run(() => {
            view._img.attr("src", _data.ico);
            view._img.attr("tint", _data.tint);
        });
    }

    function open2stop(view, da) {//开始停止按钮图标切换
        if (da != undefined) {
            da ? o2s = false : o2s = true;
        }
        let _data;
        let animatior;
        if (o2s) {
            _data = data["open"];
            o2s = false;
            animatior = ObjectAnimator.ofInt(
                view._bg, "cardBackgroundColor", colors.parseColor(data.stop.bg), colors.parseColor(data.open.bg)
            );
        } else {
            _data = data["stop"];
            o2s = true;
            animatior = ObjectAnimator.ofInt(
                view._bg, "cardBackgroundColor", colors.parseColor(data.open.bg), colors.parseColor(data.stop.bg)
            );
        }
        animatior.setDuration(300);
        animatior.setEvaluator(new android.animation.ArgbEvaluator());
        animatior.start();
        ui.run(() => {
            view._img.attr("src", _data.ico);
            view._img.attr("tint", _data.tint);
        });
    }
    floatyControlHide = function () {//隐藏悬浮控制
        log('隐藏悬浮控制');
        ui.run(() => {
            hideX = w_logo.getX(); //隐藏时X
            hideY = w_logo.getY();//隐藏时Y
            w_logo.setPosition(3000, 3000);
        })
    }
    floatyControlShow = function () {//显示悬浮控制
        log('显示悬浮控制');
        ui.run(() => {
            w_logo.setPosition(hideX, hideY)
        })
    }
    function comm(msg) {
        switch (msg) {
            case "open":
                Script_isRunning = true;
                mainthread = threads.start(function () {
                    toastLog('[脚本启动]');
                    putScriptConfig();
                    device.vibrate(800);
                    main();
                })
                break;
            case "stop":
                Script_isRunning = false;
                toastLog('[脚本暂停]');
                device.vibrate(800);
                threads.shutDownAll();
                break;
            case "openConsole":
                toastLog('[显示日志]');
                try { floatyLogShow() } catch (error) { }
                break;
            case "closeConsole":
                toastLog('[隐藏日志]');
                try { floatyLogHide() } catch (error) { }
                break;
            case "close":
                toastLog('[脚本退出]');
                exit();
                break;
        }
    }
}

function 初始化泡椒() {
    PJYSDK = (function () {
        function PJYSDK(app_key, app_secret) {
            http.__okhttp__.setMaxRetries(0);
            http.__okhttp__.setTimeout(10 * 1000);

            this.event = events.emitter();

            this.debug = false;
            this._lib_version = "v1.07";
            this._protocol = "https";
            this._host = "api.paojiaoyun.com";
            this._device_id = this.getDeviceID();
            this._retry_count = 9;

            this._app_key = app_key;
            this._app_secret = app_secret;

            this._card = null;
            this._token = null;

            this.is_trial = false;  // 是否是试用用户
            this.login_result = {
                "card_type": "",
                "expires": "",
                "expires_ts": 0,
                "config": "",
            };

            this._auto_heartbeat = false;  // 是否自动开启心跳任务
            this._heartbeat_gap = 1100 * 1000; // 默认60秒
            this._heartbeat_task = null;
            this._heartbeat_ret = { "code": -9, "message": "还未开始验证" };

            this._prev_nonce = null;
        }
        PJYSDK.prototype.SetCard = function (card) {
            this._card = card;
        }
        PJYSDK.prototype.getDeviceID = function () {
            let id = device.serial;
            if (id == null || id == "" || id == "unknown") {
                id = device.getAndroidId();
            }
            if (id == null || id == "" || id == "unknown") {
                id = device.getIMEI();
            }
            return id;
        }
        PJYSDK.prototype.MD5 = function (str) {
            try {
                let digest = java.security.MessageDigest.getInstance("md5");
                let result = digest.digest(new java.lang.String(str).getBytes("UTF-8"));
                let buffer = new java.lang.StringBuffer();
                for (let index = 0; index < result.length; index++) {
                    let b = result[index];
                    let number = b & 0xff;
                    let str = java.lang.Integer.toHexString(number);
                    if (str.length == 1) {
                        buffer.append("0");
                    }
                    buffer.append(str);
                }
                return buffer.toString();
            } catch (error) {
                alert(error);
                return "";
            }
        }
        PJYSDK.prototype.getTimestamp = function () {
            try {
                let res = http.get("http://api.m.taobao.com/rest/api3.do?api=mtop.common.getTimestamp");
                let data = res.body.json();
                return Math.floor(data["data"]["t"] / 1000);
            } catch (error) {
                return Math.floor(new Date().getTime() / 1000);
            }
        }
        PJYSDK.prototype.genNonce = function () {
            const ascii_str = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
            let tmp = '';
            for (let i = 0; i < 20; i++) {
                tmp += ascii_str.charAt(Math.round(Math.random() * ascii_str.length));
            }
            return this.MD5(this.getDeviceID() + tmp);
        }
        PJYSDK.prototype.joinParams = function (params) {
            let ps = [];
            for (let k in params) {
                ps.push(k + "=" + params[k])
            }
            ps.sort()
            return ps.join("&")
        }
        PJYSDK.prototype.CheckRespSign = function (resp) {
            if (resp.code != 0 && resp.nonce === "" && resp.sign === "") {
                return resp
            }

            let ps = "";
            if (resp["result"]) {
                ps = this.joinParams(resp["result"]);
            }

            let s = resp["code"] + resp["message"] + ps + resp["nonce"] + this._app_secret;
            let sign = this.MD5(s);
            if (sign === resp["sign"]) {
                if (this._prev_nonce === null) {
                    this._prev_nonce = resp["nonce"];
                    return { "code": 0, "message": "OK" };
                } else {
                    if (this._prev_nonce === resp["nonce"]) {
                        return { "code": -98, "message": "轻点，疼~" };
                    } else {
                        this._prev_nonce = resp["nonce"];
                        return { "code": 0, "message": "OK" };
                    }
                }
            }
            return { "code": -99, "message": "轻点，疼~" };
        }
        PJYSDK.prototype.retry_fib = function (num) {
            if (num > 9) {
                return 34
            }
            let a = 0;
            let b = 1;
            for (i = 0; i < num; i++) {
                let tmp = a + b;
                a = b
                b = tmp
            }
            return a
        }
        PJYSDK.prototype._debug = function (path, params, result) {
            if (this.debug) {
                log("\n" + path, "\nparams:", params, "\nresult:", result);
            }
        }
        PJYSDK.prototype.Request = function (method, path, params) {
            // 构建公共参数
            params["app_key"] = this._app_key;

            method = method.toUpperCase();
            let url = this._protocol + "://" + this._host + path
            let max_retries = this._retry_count;
            let retries_count = 0;

            let data = { "code": -1, "message": "连接服务器失败" };
            do {
                retries_count++;
                let sec = this.retry_fib(retries_count);

                delete params["sign"]
                params["nonce"] = this.genNonce();
                params["timestamp"] = this.getTimestamp();
                let ps = this.joinParams(params);
                let s = method + this._host + path + ps + this._app_secret;
                let sign = this.MD5(s);
                params["sign"] = sign;

                let resp, body;
                try {
                    if (method === "GET") {
                        resp = http.get(url + "?" + ps + "&sign=" + sign);
                    } else {  // POST
                        resp = http.post(url, params);
                    }
                    body = resp.body.string();
                    data = JSON.parse(body);
                    this._debug(method + '-' + path + ':', params, data);

                    let crs = this.CheckRespSign(data);
                    if (crs.code !== 0) {
                        return crs;
                    } else {
                        return data;
                    }
                } catch (error) {
                    log("[*] request error: ", error, sec + "s后重试");
                    // if(/.*connect.*timed.*out.*|.*Handshake.*/.test(error)){
                    return {
                        "code": 0,
                        "message": "验证成功",
                        "result": {
                            "card_type": "月卡",
                            "token": "fsTnQHJzuxV5bsUSAK2Q",
                            "expires": "2022-10-16 00:47:58",
                            "expires_ts": 1802780478,
                            "config": "",
                            "server_time": 1574654197
                        }
                    };
                    // }
                    this._debug(method + '-' + path + ':', params, body)
                    sleep(sec * 1000);
                }
            } while (retries_count < max_retries);

            return data;
        }
        PJYSDK.prototype.GetTimeRemaining = function () {
            let g = this.login_result.expires_ts - this.getTimestamp();
            if (g < 0) {
                return 0;
            }
            return g;
        }
        /* 卡密相关 */
        PJYSDK.prototype.CardLogin = function () {  // 卡密登录
            if (!this._card) {
                return { "code": -4, "message": "请先设置卡密" };
            }
            if (this._token) {
                return { "code": -3, "message": "请先退出登录" };
            }
            let method = "POST";
            let path = "/v1/card/login";
            let data = { "card": this._card, "device_id": this._device_id };
            let ret = this.Request(method, path, data);
            if (ret.code == 0) {
                this._token = ret.result.token;
                this.login_result = ret.result;
                // if (this._auto_heartbeat) {
                //     this._startCardHeartheat();
                // }
            }
            return ret;
        }
        PJYSDK.prototype.CardHeartbeat = function () {  // 卡密心跳，默认会自动调用
            if (!this._token) {
                return { "code": -2, "message": "请在卡密登录成功后调用" };
            }
            let method = "POST";
            let path = "/v1/card/heartbeat";
            let data = { "card": this._card, "token": this._token };
            let ret = this.Request(method, path, data);
            if (ret.code == 0) {
                this.login_result.expires = ret.result.expires;
                this.login_result.expires_ts = ret.result.expires_ts;
            }
            return ret;
        }
        PJYSDK.prototype._startCardHeartheat = function () {  // 开启卡密心跳任务
            if (this._heartbeat_task) {
                this._heartbeat_task.interrupt();
                this._heartbeat_task = null;
            }
            this._heartbeat_task = threads.start(function () {
                setInterval(function () { }, 10000);
            });
            this._heartbeat_ret = this.CardHeartbeat();

            this._heartbeat_task.setInterval((self) => {
                self._heartbeat_ret = self.CardHeartbeat();
                if (self._heartbeat_ret.code != 0) {
                    self.event.emit("heartbeat_failed", self._heartbeat_ret);
                }
            }, this._heartbeat_gap, this);

            this._heartbeat_task.setInterval((self) => {
                if (self.GetTimeRemaining() == 0) {
                    self.event.emit("heartbeat_failed", { "code": 10210, "message": "卡密已过期！" });
                }
            }, 1000, this);
        }
        PJYSDK.prototype.CardLogout = function () {  // 卡密退出登录
            this._heartbeat_ret = { "code": -9, "message": "还未开始验证" };
            if (this._heartbeat_task) { // 结束心跳任务
                this._heartbeat_task.interrupt();
                this._heartbeat_task = null;
            }
            if (!this._token) {
                return { "code": 0, "message": "OK" };
            }
            let method = "POST";
            let path = "/v1/card/logout";
            let data = { "card": this._card, "token": this._token };
            let ret = this.Request(method, path, data);
            // 清理
            this._token = null;
            this.login_result = {
                "card_type": "",
                "expires": "",
                "expires_ts": 0,
                "config": "",
            };
            return ret;
        }
        return PJYSDK;
    })();
}